# coding: utf-8

"""
compat python2xx和python3xx
https://www.cnblogs.com/gaigaige/p/7754461.html
"""

import config
from datetime import datetime


class Function(object):

    @staticmethod
    def doc(func):
        if config.VERSION == 2:
            return func.func_doc
        elif config.VERSION == 3:
            return func.__doc__

    @staticmethod
    def name(func):
        if config.VERSION == 2:
            return func.func_name
        elif config.VERSION == 3:
            return func.__name__

    @staticmethod
    def code(func):
        if config.VERSION == 2:
            return func.func_code
        elif config.VERSION == 3:
            return func.__code__

    @staticmethod
    def closure(func):
        if config.VERSION == 2:
            return func.func_closure
        elif config.VERSION == 3:
            return func.__closure__

    @staticmethod
    def globals(func):
        if config.VERSION == 2:
            return func.func_globals
        elif config.VERSION == 3:
            return func.__globals__

    @staticmethod
    def dict(func):
        if config.VERSION == 2:
            return func.func_dict
        elif config.VERSION == 3:
            return func.__dict__

    @staticmethod
    def defaults(func):
        if config.VERSION == 2:
            return func.func_defaults
        elif config.VERSION == 3:
            return func.__defaults__


class String(object):

    @staticmethod
    def to_hex(string):
        if config.VERSION == 2:
            return string.decode('hex')
        elif config.VERSION == 3:
            return bytes.fromhex(string)

    @staticmethod
    def to_byte(string):
        if config.VERSION == 2:
            return string.encoding('utf-8')
        elif config.VERSION == 3:
            return bytes(string, encoding='utf-8')

    @staticmethod
    def isinstance(string):
        if config.VERSION == 2:
            return isinstance(string, unicode)
        elif config.VERSION == 3:
            return isinstance(string, str)

    @staticmethod
    def unicode(string):
        if string and config.VERSION == 2:
            string = unicode(string)
        return string


class DateTime(object):

    @staticmethod
    def now():
        return datetime.now().strftime(config.DATETIME_FORMAT)


class Urllib(object):

    @staticmethod
    def quote(string, safe='/', encoding=None, errors=None):
        if config.VERSION == 2:
            from urllib import quote
            return quote(string, safe=safe)
        elif config.VERSION == 3:
            #ImportError
            from urllib.parse import quote
            return quote(string, safe=safe, encoding=encoding, errors=errors)


class Dict(object):

    @staticmethod
    def hash_key(dic, key):
        if config.VERSION == 2:
            return dic.has_key(key)
        elif config.VERSION == 3:
            #AttributeError:
            return key in dic


class Lxml(object):

    @staticmethod
    def from_html(content, error_num=0):
        try:
            from lxml import etree
            return etree.HTML(content)
        except (ImportError, AttributeError, Exception):
            try:
                from lxml import html
                return html.fromstring(content)
            except (ImportError, AttributeError, Exception) as ex:
                if error_num > 3:
                    raise ex
                error_num += 1
                return Lxml.from_html(content, error_num=error_num)



def Queue(maxsize=0):
    try:
        from queue import Queue as Queue
    except ImportError:
        from Queue import Queue as Queue
    return Queue(maxsize=maxsize)


def Process(group=None, target=None, name=None, daemon=False, args=()):
    if 'linux' in config.PLATFORM:
        import multiprocessing
        process = multiprocessing.Process(group=group, target=target, name=name, args=args)
        process.daemon = daemon
        process.start()
        return process
    else:
        import threading
        thread = threading.Thread(group=group, target=target, name=name, args=args)
        thread.daemon = daemon
        thread.start()
        return thread

